package com.xzz.mybatis.generator.service;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.xzz.mybatis.generator.config.MyDataSourceConfig;
import com.xzz.mybatis.generator.config.MyPackageConfig;
import com.xzz.mybatis.generator.config.MybatisPlusGeneratorConfig;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: hhz
 * @createDate: 2021-3-11
 */
@Service
public class GeneratorService {
    @Resource
    private GlobalConfig globalConfig;

    @Resource
    private InjectionConfig injectionConfig;

    @Resource
    private MyPackageConfig myPackageConfig;

    @Resource
    private MyDataSourceConfig myDataSourceConfig;

    @Resource
    private DataSourceChooseService dataSourceChooseService;

    /**
     *
     * @param model 模块名
     * @param tableInfo 表名信息
     */
    public void generateCodeFile(String datasourceCode, String model, String tableInfo){

        AutoGenerator autoGenerator = new AutoGenerator();
        //  全局默认配置
        autoGenerator.setGlobalConfig(globalConfig);

        //DataSourceConfig 配置
        DataSourceConfig dataSourceConfig = dataSourceChooseService.chooseDataSource(datasourceCode);
        if (dataSourceConfig == null) {
            throw new IllegalArgumentException("Obtain dataSource failed!");
        }
        autoGenerator.setDataSource(dataSourceConfig);

        //  包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(model);
        //  生成代码包路径
        packageConfig.setParent(myPackageConfig.getParent());
        autoGenerator.setPackageInfo(packageConfig);
        //  自定义配置
        injectionConfig.setFileOutConfigList(mapperXml(model));
        //  自定义项配置
        autoGenerator.setCfg(injectionConfig);
        autoGenerator.setTemplate(new TemplateConfig().setXml(null));

        //  策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setSuperEntityClass("com.xzz.mybatis.generator.common.MyBaseEntity");
        //非oralce继承基类后，还是要做createUser,lastUpdateUser重写, 因为表字段大写规范,@TableField被重新映射,
        // 所以mybatisplus自动填充基类字段失效
        if(!dataSourceConfig.getDbType().equals(DbType.ORACLE)) {
            strategy.setSuperEntityColumns("created", "create_user", "last_updated", "last_update_user");
        }
        strategy.setEntityLombokModel(true);
//        strategy.setSuperControllerClass("com.eptison.eop.util.orm.EpBaseController");
//        strategy.setSuperServiceClass("com.eptison.eop.util.orm.EpBaseService");
//        strategy.setSuperServiceImplClass("com.eptison.eop.util.orm.EpBaseServiceImpl");
        strategy.setInclude(tableInfo);
        strategy.setControllerMappingHyphenStyle(true);
        List<TableFill> tbList = new ArrayList<>();
        tbList.add(new TableFill("CREATED", FieldFill.INSERT));
        tbList.add(new TableFill("CREATE_USER", FieldFill.INSERT));
        tbList.add(new TableFill("LAST_UPDATED", FieldFill.INSERT_UPDATE));
        tbList.add(new TableFill("LAST_UPDATE_USER", FieldFill.INSERT_UPDATE));
        strategy.setTableFillList(tbList);
        autoGenerator.setStrategy(strategy);

        //  模板引擎
        autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        templateConfig.setService("templates/mybatisplus/service.java");
        templateConfig.setServiceImpl("templates/mybatisplus/serviceImpl.java");
        templateConfig.setEntity("templates/mybatisplus/entity.java");
        templateConfig.setXml(null);

        autoGenerator.setTemplate(templateConfig);
        //  generator execute 执行
        autoGenerator.execute();

    }

    /**
     * mapper 文件
     * @param model 模块名
     * @return list
     */
    private List<FileOutConfig> mapperXml(String model){
        //mapper.xml 文件路径
        List<FileOutConfig> fileOutConfigList = new ArrayList<>();
        File classFolder = new File(MybatisPlusGeneratorConfig.class.getResource("/").getFile());
        String projectPath = classFolder.getParentFile().getAbsolutePath();
        fileOutConfigList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                StringBuilder stringBuilder = new StringBuilder(projectPath);
                stringBuilder
                        .append("/src/")
                        .append(myPackageConfig.getParent().replaceAll("\\.","/")+'/')
                        .append(model)
                        .append("/mapper/")
                        .append(tableInfo.getEntityName())
                        .append("Mapper")
                        .append(StringPool.DOT_XML);
                return stringBuilder.toString();
            }
        });

        return fileOutConfigList;
    }
}
